Skip to content

Dynamically get path to bash - #1

Open
mikhailnov wants to merge 18 commits into
dlc:masterfrom
mikhailnov:master
Open

Dynamically get path to bash#1
mikhailnov wants to merge 18 commits into
dlc:masterfrom
mikhailnov:master

Conversation

@mikhailnov

Copy link
Copy Markdown

bash is not /bin/bash on some systems, especially BSD OSes

@mikhailnov

Copy link
Copy Markdown
Author

Also fixed how functions are defined, otherwise got:
version: command not found
mikhailnov@fdf1813

run_tests.sh covers GET/POST/cookie parsing done at source time,
param(), safe_param(), cookie(), set_cookie(), keywords(),
send_redirect(), version(). Each case runs in a pristine env -i
with a controlled CGI environment; stdout is compared byte-for-byte.
Wired up as "make check".

Co-authored-by: Z.AI GLM
sed 's/+/ /' replaced only the first "+" with a space; the remaining
ones stayed in the value and were then dropped by safe_param()'s
tr -d, e.g. msg=hello+world+123 came back as "hello world123".
Use the global substitution so every "+" is restored to a space.

Co-authored-by: Z.AI GLM
sed inserts a separator only after each \xNN token, so a literal "-"
directly before an escape produced a word like "-\xD0". The decode
loop fed it to printf as a format string, where bash parsed it as
an invalid option and output nothing: the "-" and the first byte of
the next character were silently lost, and the orphaned UTF-8
continuation byte rendered as U+FFFD, e.g.
"АО Альфа-Банк Супер" -> "АО Альфа\xef\xbf\xbdанк Супер".
Values starting with "-" were dropped the same way.

Pass '%b' as an explicit format so the token is an argument and is
never parsed as an option; \xNN expansion behaviour is unchanged.
Applied to both the param and the cookie decode loops.

Co-authored-by: Z.AI GLM
The assignment branch never set \$value but still fell through to
the final echo, so every "param name value..." and "cookie name
value..." call emitted a stray blank line (and set_cookie inherited
one per call via its inner cookie call). In CGI output that blank
line lands before the headers. Return right after the export so
setters stay silent.

Co-authored-by: Z.AI GLM
- Quote variable expansions that are safe to quote (QUERY_STRING,
  name, tmpvalue, KEYWORDS, set_cookie's inner cookie call); the
  word-splitting in the QUERY_STRING/HTTP_COOKIE parse loops stays,
  it is the parsing mechanism there.
- Replace printf-as-format in the name decoders with an explicit
  %b argument, same as the value decoders; %-escapes in names
  still decode.
- safe_param: pass arguments through as "$@" instead of unquoted $*.
- cookie(): print "$value" quoted, so listings are one name per line
  (like param) and consecutive spaces in values survive the round
  trip; same for keywords() and set_cookie().
- Drop the unused DEBUG flag.

run_tests.sh pins the changed contracts and adds coverage for what
was untested: %-escape decoding of names, consecutive spaces in
keywords/cookie/set_cookie values, and safe_param not creating
params for names with spaces. Two intentional SC2016s in the runner
are suppressed with directives. shellcheck is clean on both files;
39/39 tests pass, and the suite fails on the previous library for
every changed behaviour.

Co-authored-by: Z.AI GLM
param()/cookie() used to run env|grep|sed|cut on every call, the URL
decoding forked once per %XX escape, and the init section forked a
handful of sed/tr/echo pipelines per parameter. Replace all of that
with bash-only constructs:

- ${!var} indirection reads stored values with zero forks; a helper
  (_param_value) also feeds safe_param, whose tr(1) pipeline is gone
  (the strip set is one glob class in SAFE_STRIP)
- ${!FORM_@}/${!COOKIE_@} produce the no-argument listings
- ${var//pat/rep} plus a single "printf -v %b" decode each name and
  value in one builtin call (bash reads at most two hex digits per
  \xHH, so the old per-escape space hack is unnecessary)
- "case" replaces the echo|grep probe, read -d replaces $(cat),
  ${QUERY_STRING//[;&]/ } replaces the tr splitter

This makes the library explicitly bash-only, which the %XX decoding
already was in practice (POSIX printf has no \xHH escapes). On an
Intel N100: param x1000 8.5s -> 0.08s, source x200 14.6s -> 0.13s.

Getter lookups are now exact variable matches instead of grep BREs,
and invalid variable names yield empty values instead of grep
patterns. The full suite (39 tests) passes unchanged, shellcheck is
clean.

Co-authored-by: Z.AI GLM
The fork-free rewrite relies on dense ${var//pat/rep}, ${!var} and
${var#pat} constructs that are hard to read back. Document each
transformation with a short comment line above it, in a
"input -> output" form, e.g.

  # every % becomes \x: "user%2Ename" -> "user\x2Ename"
  name=${name//%/\\x}

Also note why SAFE_STRIP is assembled by concatenation, why the
'[.-]' deletion spares %2E/%2D, and why set_cookie keeps the space
after dropping the leading ';'. Comments only; no code changes
(39/39 tests still pass, shellcheck clean).

Co-authored-by: Z.AI GLM
The fork-free rewrite removed every external tool call, so configure
had exactly one substitution left, @bash@ in the shebang of a file
that is sourced, not executed. Meanwhile the template machinery kept
costing real effort: stale generated artifacts drifted from the
template twice in one session (a 67-month-old bashlib with VERSION
0.06, and the shebang silently reverting to /bin/sh because
bash-as-sh exports BASH, which autoconf's user-override probe picks
up), and a fresh clone could not produce a working library without
autoconf+configure first.

bashlib.in is now the tracked bashlib itself, with a plain
"#!/bin/bash" shebang (no env(1) exec; anyone on an unusual layout
can adjust the one line). A static Makefile (PREFIX ?=, DESTDIR for
packagers) replaces the generated one; configure.in, Makefile.in and
the generated artifacts are gone. Also stop clobbering PATH of the
sourcing script: the /bin:/usr/bin assignment predates the fork-free
rewrite and nothing external is called anymore.

Fresh clones now work with ". ./bashlib" directly; make check and
shellcheck pass.

Co-authored-by: Z.AI GLM
Co-authored-by: Z.AI GLM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant